<template>
  <div class="xtx-numbox">
    <div class="label" v-if="isLabel">数量</div>
    <div class="numbox">
      <a href="javascript:;" @click="decre">-</a>
      <input type="text" readonly :value="count" />
      <a href="javascript:;" @click="incre">+</a>
    </div>
  </div>
</template>

<script>
// 目标: 实现对于数量的增和减交互  并且可以限制数量的最大值和最小值
// 实现步骤:
// 1. 搭建一个结构 实现增减逻辑
// 2. 把最大最小值的控制 设计为props的传入

// v-model的目标
// <XtxNumber v-model="fatherCount"/>
// 1. input框的初始值由v-model绑定的fatherCount决定,并且传入的数据变化 初始值也变化
// 2. 在当前number组件中增减按钮修改数量的时候 这个新的数量会自动同步到v-model绑定的fatherCount上

// v-model绑定一个组件身上时 到底相当于做了什么事儿？ 三个事儿
// vue2
// 1. 给组件绑定一个默认名称为 value 的prop属性  <XtxNumber  :value="fatherCount"/>
// 2. 给组件绑定一个默认名称为 input 的自定义事件  <XtxNumber  @input="cb"/>
// 3. 在组件中如果通过$emit去触发input自定义事件 事件的实参会自动赋值给 v-model绑定的fatherCount

// vue3
// 1. 给组件绑定一个默认名称为 modelValue 的prop属性  <XtxNumber  :model-value="fatherCount"/>
// 2. 给组件绑定一个默认名称为 update:modelValue 的自定义事件  <XtxNumber  @update:model-value="cb"/>
// 3. 在组件中如果通过$emit去触发update:modelValue自定义事件 事件的实参会自动赋值给 v-model绑定的fatherCount

// 一类组件的封装  表单类组件  收集用户的输入数据  el-input el-select -> v-model
// 封装模板大体一致的，利用了v-model的语法糖做的封装

// 1. 实现父组件的数据同步到子组件  [详情组件fatherCount决定number组件的count]
// 1.1 以props的数据作为子组件中数据的初始值  const count = ref(props.fatherCount)
// 1.2 当fatherCount被修改更新时 再次完成同步  watch props.fatherCount  重新进行赋值
// 2. 实现子组件中的数据被修改时 父组件中的数据也会更新
// 触发自动绑定的自定义事件 把当前子组件中最新的值当成实参传入即可

// 语法糖: 把原本复杂的语法经过一定的封装让开发者写起来更加简单
// v-if @click v-model[父子通信 prop + emit]

import { ref, watch } from 'vue'
export default {
  name: 'XtxNumber',
  props: {
    max: {
      type: Number
    },
    min: {
      type: Number
    },
    modelValue: {
      type: Number
    },
    isLabel: {
      type: Boolean,
      default: true
    }
  },
  setup (props, ctx) {
    // 初始化的时候以v-model传入的为主
    // 如果传入的fathnerCount的值发生了变化 如何保证再次同步呢？
    const count = ref(props.modelValue)
    watch(() => {
      return props.modelValue
    }, () => {
      count.value = props.modelValue
    })
    const incre = () => {
      if (count.value === props.max) {
        return
      }
      count.value++
      // 触发事件
      ctx.emit('update:modelValue', count.value)
    }
    const decre = () => {
      if (count.value === props.min) {
        return
      }
      count.value--
      ctx.emit('update:modelValue', count.value)
    }
    return {
      count,
      incre,
      decre
    }
  }
}
</script>

<style scoped lang="less">
.xtx-numbox {
  display: flex;
  align-items: center;
  .label {
    width: 60px;
    color: #999;
    padding-left: 10px;
  }
  .numbox {
    width: 120px;
    height: 30px;
    border: 1px solid #e4e4e4;
    display: flex;
    > a {
      width: 29px;
      line-height: 28px;
      text-align: center;
      background: #f8f8f8;
      font-size: 16px;
      color: #666;
      &:first-of-type {
        border-right: 1px solid #e4e4e4;
      }
      &:last-of-type {
        border-left: 1px solid #e4e4e4;
      }
    }
    > input {
      width: 60px;
      padding: 0 5px;
      text-align: center;
      color: #666;
    }
  }
}
</style>
